package org.infinitest.swingui;

import javax.swing.*;
import static javax.swing.BorderFactory.createLineBorder;
import static java.awt.Color.*;
import java.awt.*;
import java.awt.font.TextLayout;

import org.infinitest.Status;

class CustomProgressBar extends JProgressBar
{
  private String currentTest;
  private String statusMsg;

  public CustomProgressBar()
  {
    setBorder(createLineBorder(getBackground(), 2));
    setBorderPainted(true);
    setMaximum(0);
    setMinimum(0);
    setFont(Font.decode("Arial-16"));
  }

  @Override
  public void addNotify()
  {
    super.addNotify();
    Dimension textSize = getGraphics().getFontMetrics().getStringBounds("100%", getGraphics()).getBounds().getSize();
    Dimension minSize = new Dimension(textSize.width, textSize.height + getInsetHeight());
    setPreferredSize(minSize);
    validate();
  }

  @Override
  protected void paintComponent(Graphics g)
  {
    Graphics2D g2 = (Graphics2D) g.create();
    drawBackground(g2);
    drawProgressBar(g2);
    drawText(g2);
    g2.dispose();
  }

  private void drawText(Graphics2D g2)
  {
    g2.setColor(BLACK);
    g2.setFont(getFont());
    TextLayout layout = new TextLayout(getStatusMessage(), getFont(), g2.getFontRenderContext());
    layout.draw(g2, 10, (getHeight() / 2) + getBaselineOffset(layout));
  }

  private float getBaselineOffset(TextLayout layout)
  {
    return (layout.getAscent() - layout.getDescent()) / 2;
  }

  String getStatusMessage()
  {
    if (statusMsg == null)
      return Status.INDEXING.getStatusMessage();
    String msg = statusMsg.replace("$TEST_COUNT", Integer.toString(getMaximum()));
    msg = msg.replace("$TESTS_RAN", Integer.toString(getValue()));
    msg = msg.replace("$CURRENT_TEST", getCurrentTest());
    return msg;
  }

  public String getCurrentTest()
  {
    if (currentTest == null)
      return "";
    return currentTest;
  }

  private void drawProgressBar(Graphics2D g2)
  {
    Rectangle rectangle = new Rectangle(0, 0, (int) (getPercentComplete() * getSize().getWidth()), getSize().height);
    g2.setColor(getForeground());
    Insets insets = getInsets();
    int insetWidth = getInsetWidth();
    int insetHeight = getInsetHeight();
    g2.fillRoundRect(insets.left, insets.top, rectangle.width - insetWidth, rectangle.height - (insetHeight + 1), 15, 15);
  }

  private int getInsetWidth()
  {
    Insets insets = getInsets();
    return (insets.left + insets.right);
  }

  private int getInsetHeight()
  {
    Insets insets = getInsets();
    return (insets.top + insets.bottom);
  }

  private void drawBackground(Graphics2D g2)
  {
    Rectangle rectangle = new Rectangle(getSize());
    g2.setColor(getBackground());
    g2.fill(rectangle);
  }

  public void setCurrentTest(String testName)
  {
    currentTest = testName;
  }

  public void setStatusMessage(String statusMessage)
  {
    statusMsg = statusMessage;
  }
}
